/**
 * Created by liuzengrong on 2019/8/16.
 */
import React, { Component } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { ColumnProps } from 'antd/lib/table/index.d';
import { Button, Card, Divider, Row } from 'antd';
import StandardTable from '@/components/hyperspace/components/StandardTable';
import { Field } from '@/dictionary/index.d';
import { TableListItem } from '../../components/StandardTable/data.d';
import { Config } from './data.d';
import SearchForm from './components/Search';
import CreateForm from './components/CreateForm';
import UpdateForm from './components/UpdateForm';
import styles from './index.less';
import { getFieldDefines } from '@/components/hyperspace/modules/StandardModule/utils';

/**
 * 标准组件属性列表
 */
interface StandardModuleProps {
  config: Config; // 配置显示
  data: any; // 数据源
  dispatch: any;
  namespace: string; // model命名空间
  dictionary?: Field[]; // 自定义数据字典，覆盖全局字典字典
}

interface StandardModuleState {
  createModalVisible: boolean;
  updateModalVisible: boolean;
  selectedRows: TableListItem[];
  formValues: { [key: string]: string };
  loading: boolean;
  searchStatus: any; // 状态条
  searchFormValues: { [key: string]: string }; // 查询表单
}

/**
 * 标准组件：包含操作有新增、修改、删除、条件分页查询
 */
class StandardModule extends Component<StandardModuleProps, StandardModuleState> {
  state: StandardModuleState = {
    createModalVisible: false,
    updateModalVisible: false,
    selectedRows: [],
    formValues: {},
    loading: false,
    searchStatus: '', // 状态条
    searchFormValues: {}, // 查询表单
  };

  columns: ColumnProps<TableListItem>[] = [];

  constructor(props: StandardModuleProps) {
    super(props);

    const { config, dictionary = [] } = this.props;
    if (config.list) {
      // 显示列表
      const { fields, format, extensions } = config.list;

      const fieldDefines: Field[] = getFieldDefines(fields, dictionary);

      const columnDefines = fieldDefines.map((item, key) => {
        let extension = {};
        if (format) {
          extension = format[item.name] ? format[item.name] : {};
        }
        return {
          title: item.desc,
          dataIndex: item.name,
          ...extension,
        };
      });

      let operations: any = [];

      if (config.update) operations.push({ type: 'update', config: config.update });
      if (config.delete) operations.push({ type: 'delete', config: config.delete });

      if (extensions && extensions.operations) {
        operations = operations.concat(extensions.operations);
      }

      if (operations.length > 0) {
        // eslint-disable-next-line no-shadow
        let operationsFormat = {
          title: '操作',
          dataIndex: 'operations',
          width: 200,
          fixed: 'right',
          // @ts-ignore
          render: (text: any, record: TableListItem) => (
            <span>
              {operations.map((operation: any, key: number) => {
                if (key > 0) {
                  return (
                    // eslint-disable-next-line react/no-array-index-key
                    <span key={key}>
                      <Divider type="vertical" />
                      {this.renderListOperations(operation, record, config)}
                    </span>
                  );
                }
                return (
                  // eslint-disable-next-line react/no-array-index-key
                  <span key={key}>{this.renderListOperations(operation, record, config)}</span>
                );
              })}
            </span>
          ),
        };
        // @ts-ignore
        // eslint-disable-next-line no-bitwise
        operationsFormat = Object.assign(operationsFormat, format.operations || {});
        columnDefines.push(operationsFormat);
      }
      this.columns = columnDefines;
    }

    if (config.search && config.search.tabs) {
      this.state.searchStatus = config.search.tabs.tabItems.filter(item => item.active)[0].value;
    }
  }

  componentDidMount() {
    this.handleSearch({});
  }

  /**
   * 新增按钮点击事件
   */
  handleAddClick = () => {
    this.handleAddVisible(true);
  };

  /**
   * 取消新增事件
   */
  handleAddCancelClick = () => {
    this.handleAddVisible(false);
  };

  /**
   * 是否显示新增Form
   *
   * @param visible
   */
  handleAddVisible = (visible: boolean) => {
    this.setState({
      createModalVisible: visible,
    });
  };

  /**
   * 取消修改事件
   */
  handleUpdateCancelClick = () => {
    this.handleUpdateVisible(false);
  };

  /**
   * 是否显示修改Form
   *
   * @param visible
   */
  handleUpdateVisible = (visible: boolean) => {
    this.setState({
      updateModalVisible: visible,
    });
  };

  /**
   * 新增表单提交
   *
   * @param values
   */
  handleAdd = (values: any) => {
    console.log('Add: ', values);
    const { dispatch, namespace, config } = this.props;
    if (config.add) {
      dispatch({
        type: `${namespace}/add`,
        payload: {
          ...values,
        },
        url: config.add.url,
        callback: () => {
          this.handleAddVisible(false);
          this.handleSearch({});
        },
      });
    }
  };

  /**
   * 查询按钮点击事件
   *
   * @param values
   */
  handleSearch = (values: any) => {
    if (values && JSON.stringify(values) !== '{}') {
      this.setState({
        searchFormValues: values,
      });
    } else {
      values = this.state.searchFormValues;
    }

    console.log('Search: ', { ...values, status: this.state.searchStatus });
    const { dispatch, namespace, config } = this.props;
    if (config.list) {
      dispatch({
        type: `${namespace}/select`,
        payload: {
          ...values,
          status: this.state.searchStatus,
        },
        url: config.list.url,
      });
    }
  };

  /**
   * 修改表单提交
   *
   * @param values
   */
  handleUpdate = (values: any) => {
    console.log('Update: ', values);
    const { dispatch, namespace, config } = this.props;
    if (config.update) {
      dispatch({
        type: `${namespace}/update`,
        payload: {
          ...values,
        },
        url: config.update.url,
        callback: () => {
          this.handleUpdateVisible(false);
          this.handleSearch({});
        },
      });
    }
  };

  /**
   * 删除记录
   *
   * @param values
   */
  handleDelete = (values: any) => {
    console.log('Delete: ', values);
    const { dispatch, namespace, config } = this.props;
    if (config.delete) {
      dispatch({
        type: `${namespace}/delete`,
        payload: {
          ...values,
        },
        url: config.delete.url,
        callback: () => {
          this.handleSearch({});
        },
      });
    }
  };

  /**
   * 批量删除记录
   *
   * @param values
   */
  handleBatchDelete = () => {
    const ids: any = this.state.selectedRows.map(item => item.id);
    console.log('BatchDelete: ', ids);
    const { dispatch, namespace, config } = this.props;
    if (config.delete && config.delete.batchDelete) {
      dispatch({
        type: `${namespace}/batchDelete`,
        payload: {
          ids,
        },
        url: config.delete.batchDeleteUrl,
        callback: () => {
          this.handleSearch({});
        },
      });
    }
  };

  /**
   * 捕获状态事件
   *
   * @param activeKey
   */
  handleStatus = (activeKey: any) => {
    this.setState(
      {
        searchStatus: activeKey,
      },
      () => {
        this.handleSearch({});
      },
    );
  };

  /**
   * 捕获选择事件
   *
   * @param rows
   */
  handleSelectRow = (rows: any) => {
    this.setState({
      selectedRows: rows,
    });
  };

  /**
   * 渲染列表操作
   *
   * @param operation
   * @param record
   */
  renderListOperations(operation: any, record: any, config: any) {
    if (operation.type === 'update') {
      return (
        <a
          onClick={() => {
            // @ts-ignore
            this.setState({
              formValues: record,
              createModalVisible: false,
              loading: false,
              selectedRows: [],
              updateModalVisible: false,
            });
            this.handleUpdateVisible(true);
          }}
        >
          修改
        </a>
      );
    }
    if (operation.type === 'delete') {
      return (
        <a
          onClick={() => {
            // @ts-ignore
            const primaryKeys = config.delete.fields;
            const primaryKeyItems = {};
            // eslint-disable-next-line array-callback-return
            primaryKeys.map((key: string | number) => {
              primaryKeyItems[key] = record[key];
            });
            this.handleDelete(primaryKeyItems);
          }}
        >
          删除
        </a>
      );
    }
    if (operation.type === 'line') {
      return <Divider type="vertical" />;
    }
    return typeof operation === 'function' ? operation(record) : operation;
  }

  render() {
    const {
      selectedRows,
      loading,
      updateModalVisible,
      createModalVisible,
      formValues,
    } = this.state;
    const { data, config, dictionary } = this.props;
    const { common } = config;
    const { formItemOptions = {} } = common || {};

    return (
      <PageHeaderWrapper>
        <Card bordered={false}>
          {config.search ? (
            <div className={styles.tableListForm}>
              {/* eslint-disable-next-line max-len */}
              <SearchForm
                visible
                config={config.search}
                dictionary={dictionary || []}
                onSubmit={this.handleSearch}
              />
            </div>
          ) : (
            <></>
          )}
          <Row style={{ marginBottom: 20 }}>
            {config.add ? (
              <Button type="primary" onClick={this.handleAddClick}>
                新增
              </Button>
            ) : (
              <></>
            )}
            {config.delete && config.delete.batchDelete ? (
              <Button style={{ marginLeft: 10 }} onClick={this.handleBatchDelete}>
                批量删除
              </Button>
            ) : (
              <></>
            )}
            {// eslint-disable-next-line max-len
            config.extensions && config.extensions.operations ? (
              // eslint-disable-next-line max-len
              config.extensions.operations.map(operation =>
                operation(this.state.selectedRows, this.handleSearch),
              )
            ) : (
              <></>
            )}
          </Row>
          <StandardTable
            selectedRows={selectedRows}
            onSelectRow={this.handleSelectRow}
            loading={loading}
            data={data}
            columns={this.columns}
            hideSelect={
              !(
                (config.common && config.common.selectRows) ||
                (config.delete && config.delete.batchDelete)
              )
            }
            {...(config.list && config.list.table)}
            tabs={config.search ? config.search.tabs : undefined}
            handleStatus={this.handleStatus}
            searchStatus={this.state.searchStatus}
          />
        </Card>
        {config.add ? (
          <CreateForm
            dictionary={dictionary || []}
            visible={createModalVisible}
            config={config}
            formItemOptions={formItemOptions}
            onSubmit={this.handleAdd}
            onCancel={this.handleAddCancelClick}
          />
        ) : (
          <></>
        )}
        {config.update ? (
          <UpdateForm
            dictionary={dictionary || []}
            visible={updateModalVisible}
            config={config}
            formItemOptions={formItemOptions}
            onSubmit={this.handleUpdate}
            onCancel={this.handleUpdateCancelClick}
            data={formValues}
          />
        ) : (
          <></>
        )}
      </PageHeaderWrapper>
    );
  }
}

export default StandardModule;
